import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.Set;


/**
 * 激活码生成器
 * @author 	林岑
 * @time	2012年9月4日 17:21:24
 */
public class CodeCreator {

	/**
	 * 生成数量
	 */
	private static final int COUNT = 10000;

	/**
	 * 生成的激活码长度
	 */
	private static final int LENGTH = 19;

	/**
	 * 特征码长度
	 */
	private static final int SPECIAL_CODE_LEGTN = 3;

	/** 特征码 */
	private static String specialMark;
	
	private final static String PATH = "F:/系统文件夹/桌面/礼包激活码/";

	/** 特征码配置, 该配置中, 放入了所有已经使用过的特征码 */
	private static final Properties p = new Properties();

	private static Random r = new Random();

	private static final List<Character> cs = new ArrayList<Character>();

	static {
		for (char c = 0; c <= 127; c++) 
			if(Character.isLetterOrDigit(c))
				cs.add(c);
	}

	public static void main(String[] args) throws FileNotFoundException, IOException {
		long t1 = System.currentTimeMillis();
		create();
		System.out.println(
				"生成时间:" + (System.currentTimeMillis() - t1) + "毫秒  " + "\n" + 
						" 特征码:" + specialMark + "\n" + 
						"生成随机码条数:	" + COUNT
				);
	}

	/**
	 * 生成激活码到桌面
	 * @throws IOException
	 */
	private static void create() throws IOException {
		init();
		writeToFile( createCode() );
	}


	/**
	 * 将容器s中的所有字符串, 以换行符分隔, 写入文件中.
	 * @param s
	 * @throws FileNotFoundException 
	 */
	private static void writeToFile(List<StringBuffer> s) throws FileNotFoundException {
		File f = new File(PATH + specialMark + ".txt");
		File fSql = new File(PATH + specialMark + " SQL.txt");

		PrintStream nor = new PrintStream(f);
		PrintStream sql = new PrintStream(fSql);

		nor.println(s.get(0));
		sql.println(s.get(1));
		
		nor.close();
		sql.close();
	}

	/**
	 * 生成随机码 , 放入容器中
	 * @return
	 */
	private static List<StringBuffer> createCode() {
		StringBuffer s = new StringBuffer();
		StringBuffer sqlBuffer = new StringBuffer();
		Set<String> set = new HashSet<String>();

		List<StringBuffer> ls = new ArrayList<StringBuffer>();

		String rd;
		while(set.size() < COUNT) {
			rd = getRandomString(LENGTH - SPECIAL_CODE_LEGTN);
			if(set.add(rd)) {				//如果生成的随机码没有重复, 那么就添加到字符串缓冲区中.
				s.append(specialMark);		//特征码
				s.append(rd);				//随机码
				s.append("\r\n");	

				sqlBuffer.append("INSERT INTO `table_name^_^` VALUES ('");
				sqlBuffer.append(specialMark);
				sqlBuffer.append(rd);				//随机码
				sqlBuffer.append("');");
				sqlBuffer.append("\r\n");	

			}
		}
		ls.add(s);
		ls.add(sqlBuffer);
		return ls;
	}

	/**
	 * 初始化
	 */
	private static void init() throws IOException {
		File file = new File("res/SpecialMark.properties");
		FileInputStream fo = new FileInputStream(file);
		p.load(fo);
		specialMark = getRandomSpecialCode();
		p.put(specialMark, specialMark);
		p.list(new PrintStream(file));
	}

	/**
	 * 获得长度为length的随机字符串.
	 * @param length	长度
	 */
	private static String getRandomString(int length) {
		StringBuilder s = new StringBuilder();
		for (char i = 0; i < length; i++) {
			s.append(getRandomChar());
		}
		return s.toString();
	}

	/**
	 * 获得一个随机字符
	 */
	private static char getRandomChar() {
		return cs.get(r.nextInt(cs.size()));
	}

	/**
	 * 获得一个和配置文件中不冲突的随机特征码
	 */
	private static String getRandomSpecialCode () {
		String ss = getRandomString(SPECIAL_CODE_LEGTN);
		return p.contains(ss) ? getRandomSpecialCode() : ss;
	}

}
